﻿#region Header
// ------------------------ Licence / Copyright ------------------------
// 
// ScrumTable for Scrum Meeting Support
// Copyright © HSR - Hochschule für Technik Rapperswil
// All Rights Reserved
// 
// Author:
//  Michael Gfeller Silvan Gehrig Patrick Boos
// 
// ---------------------------------------------------------------------
#endregion


#region Usings

using System;
using System.Collections.Specialized;
using System.IO;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Data;
using System.Windows.Input;
using System.Windows.Markup;
using System.Windows.Media;
using Microsoft.Surface.Presentation.Controls;
using ScrumTable.BL.DM.DataManagement;
using ScrumTable.Common.Data;
using ScrumTable.Common.FileSystem;
using ScrumTable.UI.View.Controls;
using ScrumTable.UI.View.CustomControl;
using ScrumTable.UI.View.Extension;
using ScrumTable.UI.View.Util;
using ScrumTable.UI.View.WinTouch.CustomControl;
using ScrumTable.UI.View.WinTouch.UserControls.HtmlRichText.Controls;
using ScrumTable.UI.View.WinTouch.UserControls.SubControls;
using ScrumTable.UI.View.WinTouch.UserControls.Tool;
using ScrumTable.UI.View.WinTouch.Util;
using ScrumTable.UI.ViewModel;
using ScrumTable.UI.ViewModel.Common;
using ScrumTable.Common.Collections;
using Size = System.Windows.Size;

#endregion

namespace ScrumTable.UI.View.WinTouch.UserControls
{

    

    /// <summary>
    /// Interaction logic for UserStoryControlBack.xaml
    /// </summary>
    public partial class UserStoryControlBackFullSize : IDropUserControl
    {

        #region Constructors / Destructor
        //--------------------------------------------------------------------
        // Decleration
        //--------------------------------------------------------------------

        private string _oldContextId;

        #endregion

        #region Constructors / Destructor
        //--------------------------------------------------------------------
        // Constructors / Destructor
        //--------------------------------------------------------------------
        /// <summary>
        /// Initializes a new instance of the <see cref="UserStoryControlBack"/> class.
        /// </summary>
        public UserStoryControlBackFullSize()
        {
            InitializeComponent();
            if (!System.ComponentModel.DesignerProperties.GetIsInDesignMode(this))
            {
                Loaded += OnLoaded;
                DataContextChanged += OnDataContextChanged;
            }

        }

    
        
        #endregion

        
        #region Methods
        //--------------------------------------------------------------------
        // Methods
        //--------------------------------------------------------------------
        /// <summary>
        /// Releases managed (c# or .net) resources.
        /// </summary>
        protected override void ReleaseManagedResources()
        {
            var viewModel = (DataContext as UserStoryViewModel);
            if (viewModel != null && !viewModel.IsDisposed)
            {
                viewModel.Original.Save();
            }
            base.ReleaseManagedResources();
            
        }

       
        #endregion

        #region Events
        //--------------------------------------------------------------------
        // Events
        //--------------------------------------------------------------------


        private void OnAddTaskClick(object sender, RoutedEventArgs e)
        {
            if (DataContext is UserStoryViewModel)
            {
                var task = ((UserStoryViewModel)DataContext).Original.Tasks.AddNew();
                var taskBack = new TaskControlBack() {DataContext = new TaskViewModel(task)};
                ((AppScreen)Application.Current.MainWindow).AddScatteredItem(taskBack, ((UIElement)e.OriginalSource).PointToScreen(new Point(0, 0)), true);
            }
        }

        private void OnLoaded(object sender, RoutedEventArgs e)
        {
            Title.SelectAll();
            Title.Focus();
            Loaded -= OnLoaded;
        }

        
        private void OnDataContextChanged(object sender, DependencyPropertyChangedEventArgs e)
        {
            if(e.NewValue!=null && e.OldValue !=null && e.NewValue != e.OldValue)
            {
                PropertyPart.Content = null;
                MemoPart.Content = null;
                HierarchyPlaceHolder.Content = null;
            }
            else if (_oldContextId != null && e.OldValue == null && e.NewValue != null)
            {
                if (((IScrumItemViewModel<ScrumItemBase>)e.NewValue).Id != _oldContextId)
                {
                    PropertyPart.Content = null;
                    MemoPart.Content = null;
                    HierarchyPlaceHolder.Content = null;
                    _oldContextId = null;
                }
            }
            else if (e.NewValue == null && e.OldValue != null)
            {
                _oldContextId = ((IScrumItemViewModel<ScrumItemBase>)e.OldValue).Id;
            }

            if (PropertyPart.Content == null)
            {
                PropertyPart.Content = CreateDynamicUiFactory.CreateDynamicPart(DataContext as IScrumItemViewModel<ScrumItemBase>, ElementManager.ElementConfig.StoryElement, false);
                MemoPart.Content = CreateDynamicUiFactory.CreateMemoParts(DataContext as IScrumItemViewModel<ScrumItemBase>, ElementManager.ElementConfig.StoryElement);
                if (DataContext is UserStoryViewModel)
                {
                   HierarchyPlaceHolder.Content = new AddChildTaskControl();
                }
            }
        }

        private void OnAddAttachmentClick(object sender, RoutedEventArgs e)
        {
            if (DataContext is UserStoryViewModel)
            {
                ScrumInkCanvas.CreateAndShowInkCanvas(DataContext as UserStoryViewModel);
                
            }
        }

        private void OnDropControlRoot(object sender, Microsoft.Surface.Presentation.SurfaceDragDropEventArgs e)
        {
            var card = e.Cursor.Data as ScrumPokerCard;
            if (card != null && card.CardType == ScrumPokerCardType.Number)
            {
                if (DataContext is UserStoryViewModel)
                {
                    ((UserStoryViewModel) DataContext).StoryPoints = card.Number;
                }
            }
        }
        #endregion

        private void SurfaceButton_Click(object sender, RoutedEventArgs e)
        {
            var senderControl = (Control) sender;
            var background = senderControl.Background;
            senderControl.Background = new VisualBrush(new WaitControl() { Width = ActualWidth, Height = ActualHeight });
            ((AttachmentViewModel)(((Control)sender).DataContext)).OpenInExternalProgramm(() => senderControl.Background = background);
        }

        #region IDropControl

        public FrameworkElement GetRootControl
        {
            get { return this; }
        }

        public bool ShowIconWithbackground
        {
            get { return true; }
        }

        public CanDropResult CanDrop(object objectToDrop)
        {
            return this.ConvertBoolToEnum(objectToDrop is ScrumPokerCard);
        }
        #endregion

    }


    public class ItemHeaderTemplateSelector : DataTemplateSelector
    {
        public DataTemplate ItemHeaderTemplate { get; set; }
        public DataTemplate NewButtonHeaderTemplate { get; set; }

        public override DataTemplate SelectTemplate(object item, DependencyObject container)
        {
            if (item == CollectionView.NewItemPlaceholder)
            {
                return NewButtonHeaderTemplate;
            }
            else
            {
                return ItemHeaderTemplate;
            }
        }
    }



    public class ItemContentTemplateSelector : DataTemplateSelector
    {
        public DataTemplate ItemContentTemplate { get; set; }
        public DataTemplate ItemImageContentTemplate { get; set; }

        public override DataTemplate SelectTemplate(object item, DependencyObject container)
        {
            if(item is AttachmentViewModel && ((AttachmentViewModel)item).IsImage)
            {
                return ItemImageContentTemplate;
            }
            else
            {
                return ItemContentTemplate;
            }
        }
    }


    /// <summary>
    /// from http://www.pluralsight-training.net/community/blogs/eburke/archive/2009/04/30/keeping-the-wpf-tab-control-from-destroying-its-children.aspx
    /// </summary>
    [TemplatePart(Name = "PART_ItemsHolder", Type = typeof(Panel))]
    public class TabControlStatefull : TabControl
    {
        private Panel _itemsHolder = null;

        public TabControlStatefull(): base()
        {
            // this is necessary so that we get the initial databound selected item
            this.ItemContainerGenerator.StatusChanged += OnItemContainerGeneratorStatusChanged;
        }

        /// <summary>
        /// if containers are done, generate the selected item
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void OnItemContainerGeneratorStatusChanged(object sender, EventArgs e)
        {
            if (this.ItemContainerGenerator.Status == GeneratorStatus.ContainersGenerated)
            {
                this.ItemContainerGenerator.StatusChanged -= OnItemContainerGeneratorStatusChanged;
                UpdateSelectedItem();
            }
        }

        /// <summary>
        /// get the ItemsHolder and generate any children
        /// </summary>
        public override void OnApplyTemplate()
        {
            base.OnApplyTemplate();
            _itemsHolder = GetTemplateChild("PART_ItemsHolder") as Panel;
            UpdateSelectedItem();
        }
        
        protected override DependencyObject GetContainerForItemOverride()
        {
            var item = new TabItem();
            item.PreviewTouchDown += (sender, e) =>
                                         {
                                             TabItem tab = sender as TabItem;
                                             if (tab != null)
                                             {
                                                 SelectedItem = tab.DataContext;
                                             }
                                         };
            item.PreviewMouseDown += (sender, e) =>
                                         {
                                             TabItem tab = sender as TabItem;
                                             if (tab != null)
                                             {
                                                 SelectedItem = tab.DataContext;
                                             }
                                         };
            return item;
        }

        /// <summary>
        /// when the items change we remove any generated panel children and add any new ones as necessary
        /// </summary>
        /// <param name="e"></param>
        protected override void OnItemsChanged(NotifyCollectionChangedEventArgs e)
        {
            base.OnItemsChanged(e);

            if (_itemsHolder == null)
            {
                return;
            }

            switch (e.Action)
            {
                case NotifyCollectionChangedAction.Reset:
                    _itemsHolder.Children.Clear();
                    break;

                case NotifyCollectionChangedAction.Add:
                case NotifyCollectionChangedAction.Remove:
                    if (e.OldItems != null)
                    {
                        foreach (var item in e.OldItems)
                        {
                            ContentPresenter cp = FindChildContentPresenter(item);
                            if (cp != null)
                            {
                                _itemsHolder.Children.Remove(cp);
                            }
                        }
                    }

                    // don't do anything with new items because we don't want to
                    // create visuals that aren't being shown

                    UpdateSelectedItem();
                    break;

                case NotifyCollectionChangedAction.Replace:
                    throw new NotImplementedException("Replace not implemented yet");
            }
        }

        /// <summary>
        /// update the visible child in the ItemsHolder
        /// </summary>
        /// <param name="e"></param>
        protected override void OnSelectionChanged(SelectionChangedEventArgs e)
        {
            base.OnSelectionChanged(e);
            UpdateSelectedItem();
        }

        /// <summary>
        /// generate a ContentPresenter for the selected item
        /// </summary>
        void UpdateSelectedItem()
        {
            if (_itemsHolder == null)
            {
                return;
            }

            // generate a ContentPresenter if necessary
            TabItem item = GetSelectedTabItem();
            if (item != null)
            {
                CreateChildContentPresenter(item);
            }

            // show the right child
            foreach (ContentPresenter child in _itemsHolder.Children)
            {
                child.Visibility = ((child.Tag as TabItem).IsSelected) ? Visibility.Visible : Visibility.Collapsed;
            }
        }

        /// <summary>
        /// create the child ContentPresenter for the given item (could be data or a TabItem)
        /// </summary>
        /// <param name="item"></param>
        /// <returns></returns>
        ContentPresenter CreateChildContentPresenter(object item)
        {
            if (item == null)
            {
                return null;
            }

            ContentPresenter cp = FindChildContentPresenter(item);

            if (cp != null)
            {
                return cp;
            }

            // the actual child to be added.  cp.Tag is a reference to the TabItem
            cp = new ContentPresenter();
            cp.Content = (item is TabItem) ? (item as TabItem).Content : item;
            cp.ContentTemplate = this.SelectedContentTemplate;
            cp.ContentTemplateSelector = this.SelectedContentTemplateSelector;
            cp.ContentStringFormat = this.SelectedContentStringFormat;
            cp.Visibility = Visibility.Collapsed;
            cp.Tag = (item is TabItem) ? item : (this.ItemContainerGenerator.ContainerFromItem(item));
            _itemsHolder.Children.Add(cp);
            return cp;
        }

        /// <summary>
        /// Find the CP for the given object.  data could be a TabItem or a piece of data
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        ContentPresenter FindChildContentPresenter(object data)
        {
            if (data is TabItem)
            {
                data = (data as TabItem).Content;
            }

            if (data == null)
            {
                return null;
            }

            if (_itemsHolder == null)
            {
                return null;
            }

            foreach (ContentPresenter cp in _itemsHolder.Children)
            {
                if (cp.Content == data)
                {
                    return cp;
                }
            }

            return null;
        }

        /// <summary>
        /// copied from TabControl; wish it were protected in that class instead of private
        /// </summary>
        /// <returns></returns>
        protected TabItem GetSelectedTabItem()
        {
            object selectedItem = base.SelectedItem;
            if (selectedItem == null)
            {
                return null;
            }
            TabItem item = selectedItem as TabItem;
            if (item == null)
            {
                item = base.ItemContainerGenerator.ContainerFromIndex(base.SelectedIndex) as TabItem;
            }
            return item;
        }
    }
}
